package bug.servlet;


/**
 * User: ion
 * Date: Feb 27, 2011 - 3:17:51 PM
 */

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.context.request.WebRequest;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

public class OpenSessionInViewInterceptorFilter extends ContextRetainingFilterAdapter {
    private String interceptorBeanName;
    protected final Log log = LogFactory.getLog(getClass());

    public void init(FilterConfig filterConfig) throws ServletException {
        super.init(filterConfig);
        setInterceptorBeanName(filterConfig.getInitParameter("interceptorBeanName"));
    }

    /**
     * @see org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor
     * @see org.springframework.web.servlet.HandlerInterceptor#afterCompletion
     */
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpReq = ((HttpServletRequest) request);

        if (log.isDebugEnabled()) {
            log.debug(">>> Opening session for request " + httpReq.getMethod() + ' ' + httpReq.getRequestURI());
        }

        OpenSessionInViewInterceptor interceptor = (OpenSessionInViewInterceptor) getApplicationContext().getBean(getInterceptorBeanName());
        WebRequest webRequest = new ServletWebRequest(httpReq);
        interceptor.preHandle(webRequest);

        try {
            chain.doFilter(request, response);
            interceptor.postHandle(webRequest, null);
        } catch (IOException e) {
            log.error(">>> IOException:", e);
            throw e;
        } catch (ServletException e) {
            log.error(">>> ServletException:", e);
            throw e;
        } catch (RuntimeException e) {
            log.error(">>> RuntimeException:", e);
            throw e;
        } finally {
            interceptor.afterCompletion(webRequest, null);
            log.debug(">>> Session closed");
        }
    }

    public String getInterceptorBeanName() {
        return interceptorBeanName;
    }

    public void setInterceptorBeanName(String interceptorBeanName) {
        this.interceptorBeanName = interceptorBeanName;
    }
}
